from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import status
from django.db.models import Q
from django.http import HttpResponse
import openpyxl
from openpyxl.styles import Font
from datetime import datetime

from ..models import MonitorTarget, Keyword
from ..serializers import MonitorTargetSerializer

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_monitor_targets(request):
    """获取监控目标列表，支持分页、搜索和过滤"""
    try:
        # 获取查询参数
        page = int(request.GET.get('page', 1))
        page_size = int(request.GET.get('pageSize', 10))
        search = request.GET.get('search', '')
        target_type = request.GET.get('type', '')
        is_priority = request.GET.get('is_priority', '')
        
        # 构建查询条件
        query = Q()
        
        if search:
            query |= Q(name__icontains=search)
            query |= Q(description__icontains=search)
            query |= Q(keywords__word__icontains=search)
        
        if target_type:
            query &= Q(type=target_type)
            
        if is_priority:
            is_priority_bool = is_priority.lower() == 'true'
            query &= Q(is_priority=is_priority_bool)
        
        # 执行查询
        targets = MonitorTarget.objects.filter(query).distinct()
        
        # 计算总数
        total = targets.count()
        
        # 分页
        start = (page - 1) * page_size
        end = start + page_size
        targets_page = targets[start:end]
        
        # 序列化
        serializer = MonitorTargetSerializer(targets_page, many=True)
        
        return Response({
            'success': True,
            'total': total,
            'data': serializer.data
        })
    except Exception as e:
        return Response({
            'success': False,
            'message': f'获取监控目标失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_monitor_target(request, target_id):
    """获取单个监控目标详情"""
    try:
        target = MonitorTarget.objects.get(id=target_id)
        serializer = MonitorTargetSerializer(target)
        return Response({
            'success': True,
            'data': serializer.data
        })
    except MonitorTarget.DoesNotExist:
        return Response({
            'success': False,
            'message': '监控目标不存在'
        }, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({
            'success': False,
            'message': f'获取监控目标详情失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['POST'])
@permission_classes([IsAuthenticated])
def create_monitor_target(request):
    """创建新的监控目标"""
    try:
        data = request.data
        keywords_data = data.pop('keywords', [])
        
        serializer = MonitorTargetSerializer(data=data)
        if serializer.is_valid():
            target = serializer.save()
            
            # 处理关键词
            if keywords_data:
                for keyword_id in keywords_data:
                    try:
                        keyword = Keyword.objects.get(id=keyword_id)
                        target.keywords.add(keyword)
                    except Keyword.DoesNotExist:
                        pass
            
            return Response({
                'success': True,
                'message': '监控目标创建成功',
                'data': MonitorTargetSerializer(target).data
            }, status=status.HTTP_201_CREATED)
        else:
            return Response({
                'success': False,
                'message': '验证失败',
                'errors': serializer.errors
            }, status=status.HTTP_400_BAD_REQUEST)
    except Exception as e:
        return Response({
            'success': False,
            'message': f'创建监控目标失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def update_monitor_target(request, target_id):
    """更新监控目标"""
    try:
        target = MonitorTarget.objects.get(id=target_id)
        data = request.data
        keywords_data = data.pop('keywords', None)
        
        serializer = MonitorTargetSerializer(target, data=data, partial=True)
        if serializer.is_valid():
            updated_target = serializer.save()
            
            # 处理关键词
            if keywords_data is not None:
                # 清除现有关键词
                updated_target.keywords.clear()
                # 添加新关键词
                for keyword_id in keywords_data:
                    try:
                        keyword = Keyword.objects.get(id=keyword_id)
                        updated_target.keywords.add(keyword)
                    except Keyword.DoesNotExist:
                        pass
            
            return Response({
                'success': True,
                'message': '监控目标更新成功',
                'data': MonitorTargetSerializer(updated_target).data
            })
        else:
            return Response({
                'success': False,
                'message': '验证失败',
                'errors': serializer.errors
            }, status=status.HTTP_400_BAD_REQUEST)
    except MonitorTarget.DoesNotExist:
        return Response({
            'success': False,
            'message': '监控目标不存在'
        }, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({
            'success': False,
            'message': f'更新监控目标失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['DELETE'])
@permission_classes([IsAuthenticated])
def delete_monitor_target(request, target_id):
    """删除监控目标"""
    try:
        target = MonitorTarget.objects.get(id=target_id)
        target.delete()
        return Response({
            'success': True,
            'message': '监控目标删除成功'
        })
    except MonitorTarget.DoesNotExist:
        return Response({
            'success': False,
            'message': '监控目标不存在'
        }, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({
            'success': False,
            'message': f'删除监控目标失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['PATCH'])
@permission_classes([IsAuthenticated])
def update_priority_status(request, target_id):
    """更新监控目标的优先级状态"""
    try:
        target = MonitorTarget.objects.get(id=target_id)
        is_priority = request.data.get('is_priority')
        
        if is_priority is None:
            return Response({
                'success': False,
                'message': '缺少必要参数: is_priority'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        target.is_priority = is_priority
        target.save()
        
        return Response({
            'success': True,
            'message': f'监控目标已{"设为重点监控" if is_priority else "取消重点监控"}',
            'data': MonitorTargetSerializer(target).data
        })
    except MonitorTarget.DoesNotExist:
        return Response({
            'success': False,
            'message': '监控目标不存在'
        }, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({
            'success': False,
            'message': f'更新监控目标状态失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def export_monitor_targets(request):
    """导出监控目标数据"""
    try:
        # 获取查询参数
        search = request.GET.get('search', '')
        target_type = request.GET.get('type', '')
        is_priority = request.GET.get('is_priority', '')
        
        # 构建查询条件
        query = Q()
        
        if search:
            query |= Q(name__icontains=search)
            query |= Q(description__icontains=search)
            query |= Q(keywords__word__icontains=search)
        
        if target_type:
            query &= Q(type=target_type)
            
        if is_priority:
            is_priority_bool = is_priority.lower() == 'true'
            query &= Q(is_priority=is_priority_bool)
        
        # 执行查询
        targets = MonitorTarget.objects.filter(query).distinct()
        
        # 创建工作簿
        workbook = openpyxl.Workbook()
        worksheet = workbook.active
        worksheet.title = "监控目标"
        
        # 设置表头
        headers = [
            'ID', '名称', '类型', '描述', '是否重点监控', 
            '关键词', '创建时间', '更新时间'
        ]
        for col_num, header in enumerate(headers, 1):
            cell = worksheet.cell(row=1, column=col_num)
            cell.value = header
            cell.font = Font(bold=True)
        
        # 添加数据
        type_map = {
            1: "企业",
            2: "人物",
            3: "事件",
            4: "其他"
        }
        
        for row_num, target in enumerate(targets, 2):
            # 获取关联的关键词
            keywords = ', '.join([kw.word for kw in target.keywords.all()])
            
            # 写入数据
            worksheet.cell(row=row_num, column=1).value = target.id
            worksheet.cell(row=row_num, column=2).value = target.name
            worksheet.cell(row=row_num, column=3).value = type_map.get(target.type, str(target.type))
            worksheet.cell(row=row_num, column=4).value = target.description
            worksheet.cell(row=row_num, column=5).value = "是" if target.is_priority else "否"
            worksheet.cell(row=row_num, column=6).value = keywords
            worksheet.cell(row=row_num, column=7).value = target.created_at.strftime('%Y-%m-%d %H:%M:%S')
            worksheet.cell(row=row_num, column=8).value = target.updated_at.strftime('%Y-%m-%d %H:%M:%S')
        
        # 调整列宽
        for col in worksheet.columns:
            max_length = 0
            column = col[0].column_letter
            for cell in col:
                if cell.value:
                    max_length = max(max_length, len(str(cell.value)))
            adjusted_width = (max_length + 2)
            worksheet.column_dimensions[column].width = adjusted_width
        
        # 创建响应
        response = HttpResponse(
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename=监控目标数据_{datetime.now().strftime("%Y%m%d")}.xlsx'
        
        # 保存工作簿到响应
        workbook.save(response)
        return response
    except Exception as e:
        return Response({
            'success': False,
            'message': f'导出监控目标数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 